///////////////////////////////////////////////////////////////////////////////
// This example demonstrates how to capture images into user-allocated buffer memory.
// The captured images will be saved to BMP files. 	
//
#define _WIN32_WINNT 0x0600

#include <iostream>

#include <tisudshl.h>
#include "../Common/CmdHelper.h"

using namespace DShowLib;

int		main(int argc, char* argv[])
{
	// Initialize the library.
	DShowLib::InitLibrary();


//<<setupdev
	Grabber grabber;
	if( !setupDeviceFromFile( grabber ) )
	{
		return -1;
	}
//>>

	grabber.setOverlayBitmapPathPosition( ePP_NONE );

//<<setupsink
	// Create a FrameSnapSink with an image buffer format to eY800.
	// eY800 means monochrome, 8 bits (1 byte) per pixel.	
    tFrameSnapSinkPtr pSink = FrameSnapSink::create( eY800 );

	// Set the sink.
	grabber.setSinkType( pSink );	

	// Prepare the live mode, to get the output size of the sink.
	if( !grabber.prepareLive( false ) )
	{
		std::cerr << "Could not render the VideoFormat into a eY800 sink.";
		return -1;
	}

	// Retrieve the output type and dimension of the sink
	// The dimension of the sink could be different from the VideoFormat, when
	// you use filters.
	FrameTypeInfo info;
	pSink->getOutputFrameType( info );
//>>
        
//<<createbuffers
	// Declare an array of 5 pointers to user buffers
    BYTE* pBuf[5] = {};

    tFrameQueueBufferList lst;
    for( int i = 0; i < 5; ++i )
    {
		// Create buffer
        pBuf[i] = new BYTE[info.buffersize];

		// Create a FrameQueueBuffer that objects that wraps the memory of our user buffer
        tFrameQueueBufferPtr ptr;
        Error err = createFrameQueueBuffer( ptr, info, pBuf[i], info.buffersize, NULL );
        if( err.isError() ) {
            std::cerr << "Failed to create buffer due to " << err.toString() << "\n";
            return -1;
        }
        lst.push_back( ptr );
    }
//>>

//<<saveimages
	// Start live mode for fast snapping. The live video will not be displayed,
	// because false is passed to startLive().
	grabber.startLive( false );
	
	// Snap 5 images. The list of buffers we pass to snapSequence will be filled
	// with the next 5 images the sink receives
	Error err = pSink->snapSequence( lst, lst.size() );
    if( err.isError() ) {
        std::cerr << "Failed to snap into buffers due to " << err.toString() << "\n";
        return -1;
    }
	
	// Stop the live video.
	grabber.stopLive();
	
	// Close the device.
	grabber.closeDev();

	// Save the five captured images to bitmap files.
    for( int idx = 0; idx < 5; ++idx )
    {
        wchar_t buf[MAX_PATH] = {};
        swprintf_s( buf, L"file%d.bmp", idx );

        saveToFileBMP( *(lst[idx]), buf );
    }
//>>

//<<cleanupbuffers
	// Destroy the FrameQueueBuffer objects
	lst.clear();

	// Free the five user buffers
	for( int j = 0; j < 5; ++j )
	{
		delete pBuf[j];
	}
//>>

	return 0;
}

